home *** CD-ROM | disk | FTP | other *** search
- # include <stdio.h>
- # include <ingres.h>
- # include <aux.h>
- # include <tree.h>
- # include <pv.h>
- # include "parser.h"
- # include <symbol.h>
- # include <malloc.h>
- # include <errors.h>
-
- /*
- ** TREE
- ** FUNCTION TO ADD NODE TO QUERY TREE
- ** RETURN VALUE IS POINTER TO NODE JUST CREATED
- */
- QTREE *
- tree(lptr, rptr, typ, len, valu, attnum)
- QTREE *lptr;
- QTREE *rptr;
- char typ;
- int len;
- register int valu;
- register struct atstash *attnum;
- {
- register QTREE *tptr;
- extern char Trfrmt;
- extern char Trfrml;
- extern char *need();
- extern QTREE *norm();
- extern int Err_current;
-
- # ifdef xPTR3
- tTfp(55, 0, "tree type(%d), len(%d), value(%d).\n", typ, len, valu);
- # endif
-
- if (Err_current)
- return (NULL);
-
- /* Following is a hack. Sorry about that John. */
- if (typ == AND)
- len = sizeof (struct rootnode) - sizeof (short);
-
- tptr = (QTREE *) need(Qbuf, QT_HDR_SIZ + len);
- tptr->left = lptr;
- tptr->right = rptr;
- tptr->sym.type = typ;
- tptr->sym.len = len;
-
- switch (typ)
- {
- case VAR:
- tptr->sym.value.sym_var.varno = valu & I1MASK;
- tptr->sym.value.sym_var.attno = attnum->atbid;
- tptr->sym.value.sym_var.varfrmt = attnum->atbfrmt;
- tptr->sym.value.sym_var.varfrml = attnum->atbfrml;
- tptr->sym.value.sym_var.valptr = NULL;
- tptr->sym.value.sym_var.varstr = NULL;
- break;
-
- case ROOT:
- case AGHEAD:
- tptr->sym.value.sym_root.rootuser = valu;
- break;
-
- case TREE:
- case BYHEAD:
- case AND:
- case OR:
- case QLEND:
- break;
-
- case UOP:
- case BOP:
- tptr->sym.value.sym_op.opno = valu;
- format(tptr);
- break;
-
- case COP:
- if ((tptr->sym.value.sym_op.opno = getcop(valu)) == BADCOP)
- {
- /* bad const operator */
- par_error(BADCONSTOP, WARN, valu, 0);
- return(NULL);
- }
- break;
-
- case AOP:
- format(tptr->right);
- tptr->sym.value.sym_op.agfrmt = Trfrmt;
- tptr->sym.value.sym_op.agfrml = Trfrml;
-
- case RESDOM:
- tptr->sym.value.sym_resdom.resno = valu;
- format(tptr);
- tptr->sym.value.sym_resdom.resfrmt = Trfrmt;
- tptr->sym.value.sym_resdom.resfrml = Trfrml;
- break;
-
- default:
- /* INT, FLOAT, CHAR */
- bmove(valu, &tptr->sym.value, len & I1MASK);
- break;
- }
- return (tptr);
- }
-
- /*
- ** WINDUP
- ** assign resno's to resdoms of an agg fcn
- */
- windup(ptr)
- QTREE *ptr;
- {
- register int tot;
- register int kk;
- register QTREE *t;
-
- /* COUNT THE RESDOM'S OF THIS TARGET LIST */
- kk = 1;
- for (t = ptr; t; t = t->left)
- kk++;
- tot = 1;
- for (t=ptr; t;t = t->left)
- t->sym.value.sym_resdom.resno = kk - tot++;
- }
-
- /*
- ** ADDRESDOM - makes a new entry for the target list
- **
- ** Trname must contain the name of the resdom to
- ** use for the header, create and Rsdmno for append, replace
- **
- ** the parameters are pointers to the subtrees to be
- ** suspended from the node
- */
- QTREE *
- addresdom(lptr, rptr)
- QTREE *lptr, *rptr;
- {
- register QTREE *rtval;
- register struct atstash *aptr;
- char buf[10]; /* buffer type and length in ascii for dbu */
-
- extern int Opflag;
- extern int Rsdmno;
- extern int Equel;
- extern int Resrng;
- extern char Trfrmt;
- extern char Trfrml;
- extern char *Trname;
- extern PARRNG Parrng[];
-
- extern QTREE *tree();
- extern struct atstash *attlookup();
-
- int temp;
-
- switch (Opflag)
- {
- case mdSTOP:
- rtval = NULL;
- break;
- case mdRETR:
- case mdRET_UNI:
- case mdVIEW:
- Rsdmno++;
- if (Rsdmno >= MAXDOM)
- /* too many resdoms */
- par_error(RESXTRA, FATAL, 0);
- rtval = tree(lptr, rptr, RESDOM, sizeof (struct resdomnode), Rsdmno);
- if (!Equel || Resrng)
- {
- /* buffer info for header or CREATE */
- setp(PV_STR, Trname);
-
- buf[0] = Trfrmt & I1MASK;
- smove(iocv(Trfrml & I1MASK), &buf[1]);
-
- setp(PV_STR, buf);
- }
- break;
-
- default:
- /*
- ** for append and replace, the result domain
- ** number is determined by the location of
- ** the attribute in the result relation
- */
- if (sequal(Trname, "tid"))
- /* attrib not found */
- par_error(NOATTRIN, WARN, Trname,
- trim_relname(Parrng[Resrng].vardesc.reldum.relid), 0);
- # ifdef DISTRIB
- if (sequal(Trname, "sid"))
- /* attrib not found */
- par_error(NOATTRIN, WARN, Trname,
- trim_relname(Parrng[Resrng].vardesc.reldum.relid), 0);
- # endif
- aptr = attlookup(Resrng, Trname);
- Rsdmno = aptr->atbid;
- rtval = tree(lptr, rptr, RESDOM, sizeof (struct resdomnode), Rsdmno);
- if (Opflag != mdPROT) /* INTEGRITY not possible here */
- attcheck(aptr);
- break;
- }
- return (rtval);
- }
- /*
- ** GETCOP
- ** routine to lookup 'string' in constant operators table
- ** constant table is declared in tables.y
- ** structure is defined in ../parser.h
- */
- getcop(string)
- char *string;
- {
- register struct constop *cpt;
- register char *sptr;
- extern struct constop Coptab[];
-
- sptr = string;
- for (cpt = Coptab; cpt->copname; cpt++)
- if (sequal(sptr, cpt->copname))
- return (cpt->copnum);
- return (BADCOP);
- }
-
- /*
- ** SUBSTRING
- ** creates structure to save delimiters of a substring
- ** structure is defined in ../h/tree.h
- */
- STRKEEPER
- *substring(str,isname)
- char *str;
- int isname;
- {
- extern char *need();
- STRKEEPER *s;
-
- s = (STRKEEPER *) need(Qbuf,sizeof(STRKEEPER));
- s->number[1] = s->number[0] = 1;
- s->string[1] = NULL;
- s->flag[0] = s->flag[1] = 0;
- s->string[0] = str;
- if (isname)
- s->flag[0] = 1;
- if (str == NULL)
- s->flag[0] |= 2;
- return(s);
- }
-
- STRKEEPER
- *endvals(interval,left,right)
- STRKEEPER *interval;
- int left,right;
- {
- if (left == '(')
- interval->type[0] = OPEN;
- else
- interval->type[0] = CLOSED;
- if (right == ')')
- interval->type[1] = OPEN;
- else
- interval->type[1] = CLOSED;
- return(interval);
- }
-
- setnumber(interval,num)
- STRKEEPER *interval;
- short *num;
- {
- interval->number[0] = *num;
- }
-
-
- groupstrings(left,right)
- STRKEEPER *left,*right;
- {
- left->string[1] = right->string[0];
- left->flag[1] = right->flag[0];
- left->number[1] = right->number[0];
- }
-
-
- /*
- ** CHECK_BNF -- check the legality of a simplified BNF defnition
- **
- ** Parameters:
- ** str-- the string to be checked
- **
- ** Returns:
- ** 0 - the string is legal
- ** <0 - the string is not legal
- ** -1 : bracket,brace not matched
- ** -2 : hyphen misused
- **
- ** Called by:
- ** make_tuples
- **
- ** Comments:
- ** the string may not contain nested braces or brackets
- ** these chars have special meaning and must be
- ** backslashed: { } [ ] - \
- **
- */
-
- check_bnf(str)
- char *str;
- {
- char *temp; /* temp ptr to string */
- int len; /* length of string */
- char ch; /* ptr to one char of string */
- char nextch;
- int inbrace=0; /* keeps track of braces */
- int inbrak=0; /* keeps track of brackets */
-
-
- len = strlen(str);
- temp = str;
-
- while (len > 0)
- {
- len--;
- ch = *temp++;
-
- switch (ch)
- {
- case LBRACKET:
- if (!inbrace)
- inbrak++;
- else
- return(-1);
- break;
- case RBRACKET:
- inbrak--;
- if (inbrak != 0)
- return(-1);
- break;
- case LBRACE:
- if (!inbrak)
- inbrace++;
- else
- return(-1);
- break;
- case RBRACE:
- inbrace--;
- if (inbrace != 0)
- return(-1);
- break;
- case '-':
- return(-2);
- break;
- case '\\':
- *temp++;
- break;
- default:
- nextch = *temp;
- if (nextch == '-')
- {
- *temp++;
- len--;
- if (!len)
- return(-2);
- ch = *temp;
- switch(ch)
- {
- case LBRACKET:
- case RBRACKET:
- case LBRACE:
- case RBRACE:
- case '-':
- return(-2);
- break;
- case '\\':
- *temp++;
- break;
- default:
- break;
- }
- }
- }
- }
- if ((inbrace) || (inbrak))
- return(-1);
- return(0);
- }
-
-
- /*
- ** MAKE_TUPLES -- create the tuples for the 'rdelim' relation
- ** as specified by a user-defined delimitor
- **
- ** Paramaters:
- ** desc--descriptor for the relation
- ** group--group name for the delimitor
- ** delim--name of the delimitor
- ** str-bnf string specifying the delimitor
- **
- ** Returns:
- ** 0 if successful
- ** <0 if not successful
- ** -1,-2: BNF expression not legal
- **
- */
- make_tuples(desc,group,delim,str)
- DESC *desc;
- char *group;
- char *delim;
- char *str;
- {
- int err; /* error status of bnf string */
- char *map; /* pointer to next string to make into bitmap */
- int len; /* len of str */
- int mlen; /* len of substring to make into bitmap */
- int order; /* order of bitmap */
- int type; /* type of interval ONE or ZEROMORE */
- char ch; /* pointer to current char */
-
- err = check_bnf(str);
- if (err < 0)
- return(err);
-
- len = strlen(str);
- order = 0;
-
- while (len > 0)
- {
- order++;
- map = str;
- mlen = 0;
-
- ch = *str++;
- len--;
-
- switch (ch)
- {
- case LBRACKET:
- type = ONE;
- map = str;
- while ((ch = *str++) != RBRACKET)
- {
- mlen++;
- len--;
- if (ch == '\\')
- {
- ch = *str++;
- mlen++;
- len--;
- }
- }
- len--;
- break;
-
- case LBRACE:
- type = ZEROMORE;
- map = str;
- while ((ch = *str++) != RBRACE)
- {
- mlen++;
- len--;
- if (ch == '\\')
- {
- ch = *str++;
- mlen++;
- len--;
- }
- }
- len--;
- break;
-
- default:
- type = ONE;
- if (ch == '\\')
- {
- map = str;
- ch = *str++;
- len--;
- mlen = 1;
- }
- if (*str == '-')
- {
- *str++;
- len--;
- mlen++;
- *str++;
- len--;
- mlen++;
- }
- else
- mlen = 1;
- break;
- }
-
- create_tup(desc,order,group,delim,type,map,mlen);
- }
- return(0);
- }
-
-
-
- /*
- ** CREATE_TUP-- create a tuple in the 'rdelim' relation
- **
- ** Parameters:
- ** desc - descriptor for the relation
- ** order - order field for tuple
- ** group - group field for tuple
- ** delim - delim field for tuple
- ** type - type field for tuple
- ** str - string to be converted into bitmap
- ** strlen - length of str
- **
- ** Called by:
- ** make_tuples
- */
- create_tup(desc,order,group,delim,type,str,strlen)
- DESC *desc;
- int order;
- char *group;
- char *delim;
- int type;
- char *str;
- int strlen;
- {
- DELIM_TUP *tuple;
- char bitmap[BITMAPLEN];
- TID *tid;
- char *make_dmap();
- char b[BITMAPLEN];
- int i;
-
-
- tuple = (DELIM_TUP *) malloc (sizeof(DELIM_TUP));
- tuple->order = order;
- strcpy(tuple->group,group);
- strcpy(tuple->delim,delim);
- tuple->type = type;
-
- make_dmap(str,strlen,b);
- for ( i= 0; i< BITMAPLEN; i++)
- tuple->bitmap[i] = b[i];
-
- insert(desc,&tid,tuple,1);
- }
-
-
- /*
- ** MAKE_DMAP -- given a BNF string, make the corresponding bitmap
- **
- ** Parameters:
- ** str - BNF string
- ** len - length of string
- **
- ** Called by:
- ** create_tup
- **
- ** Returns:
- ** pointer to the bitmap of 16 chars
- **
- ** Comments:
- ** The bitmap is formed of 16 chars. The total bits
- ** (128) represents the characters of the ASCII set.
- ** If the BNF string indicates a character, the bit
- ** corresponding to that char is set in the bitmap.
- ** All other bits are reset.
- */
- char *
- make_dmap(str,len,b)
- char *str;
- int len;
- char *b;
- {
- char ch;
- char nextch;
- int i;
-
- # ifdef xPTR3
- tTfp(42,0,"DMAP: str = %s, len = %d\n",str,len);
- # endif
- for (i = 0; i < ACHARS; i++)
- reset(b,i);
-
- while (len > 0)
- {
- ch = *str++;
- len--;
- if (ch == '\\')
- {
- ch = *str++;
- len--;
- }
- if ( (len > 0) && (*str == '-'))
- {
- *str++;
- len--;
- nextch = *str++;
- len--;
- for (i = ch; i <= nextch; i++)
- {
- set(b,i);
- }
- }
- else
- {
- set(b,ch);
- }
- }
- return(b);
- }
-
- /*
- ** SET,RESET -- bitmap setting routines
- **
- ** Parameters:
- ** map: the array of chars which forms the bitmap
- ** n: the bit to set or reset
- **
- ** Called by:
- ** make_bitmap
- **
- */
- set(map,n)
- char *map;
- int n;
- {
- map[n/BITS] |= (1<<(n%BITS));
- }
-
- reset(map,n)
- char *map;
- int n;
- {
- map[n/BITS] &= ((1<<(n%BITS)) ^ MAXFIELD);
- }
-
- test(map,n)
- char *map;
- int n;
- {
- return ((map[n/BITS] & (1<<(n%BITS))) != 0);
- }
-
- /*
- ** MAKE_LIST -- puts the delimitors to be used in the delim queue
- **
- ** Parameters:
- ** desc - descriptor for the relation
- ** group - group of delims to use
- **
- ** Returns:
- ** 0 if ok
- ** -1 if no delims could be found in the specified group
- **
- ** Comments:
- ** given a group name, adds all delimitors in that
- ** group to the head of the delim queue, which is
- ** pointed to by Delimhead.
- ** if the queue is empty, the predefined delimitors
- ** 'w' and 'c' will be added to the list
- */
-
- extern DELIMLIST *Delimhead;
-
- make_list(desc,group)
- DESC *desc;
- char *group;
- {
- DELIM_TUP tuple;
- TID lotid, hitid;
- DELIMLIST *d;
- DMAP *map, *m;
- char delim[12];
- int start = 1;
- int i;
- int notfound = 1;
-
- # ifdef xPTR3
- tTfp(42,0,"Make_list: group = %s\n", group);
- # endif
- if (!strcmp (group,"system"))
- {
- predef_delims();
- return(0);
- }
- if (find(desc,LRANGEKEY, &lotid, &hitid, group) < 0)
- return(-1);
- find(desc,HRANGEKEY, &lotid, &hitid, group);
- while (!get(desc, &lotid, &hitid, &tuple, 1))
- {
- if (strcmp(tuple.group, group))
- {
- continue;
- }
- notfound = FALSE;
- /* check if it is a new delimitor */
- if (strcmp(tuple.delim, delim))
- start = 1;
-
- /* start a new delimitor node */
- if (start)
- {
- d = (DELIMLIST *) malloc( sizeof(DELIMLIST));
- strcpy(delim, tuple.delim);
- strcpy(d->group,tuple.group);
- strcpy(d->delim,delim);
- d->back = Delimhead;
- Delimhead = d;
-
- map = (DMAP *) malloc(sizeof(DMAP));
- map->order = tuple.order;
- map->type = tuple.type;
- for ( i = 0; i < BITMAPLEN; i++)
- map->bits[i] = tuple.bitmap[i];
- map->next = NULL;
- d->maptr = map;
- m = map;
- start = 0;
-
- }
- else /* add another bitmap to the delimitor node */
- {
- map = (DMAP *) malloc(sizeof(DMAP));
- map->order = tuple.order;
- map->type = tuple.type;
- for ( i = 0; i < BITMAPLEN; i++)
- map->bits[i] = tuple.bitmap[i];
- map->next = NULL;
- m->next = map;
- m = m->next;
-
- }
-
- }
- /*prlist(Delimhead); */
- if (notfound)
- return(-1);
- return(0);
- }
-
- /*
- ** PREDEF_DELIMS - add the predefined delims to the queue
- **
- ** Called by:
- ** make_list
- **
- ** Side Effects:
- ** the delim queue pointed to by Delimhead
- ** is initialized with the delims 'w' and 'c'.
- **
- */
- predef_delims()
- {
- DELIMLIST *d;
- DMAP *m, *m2;
- int i;
-
- d = (DELIMLIST * ) malloc(sizeof(DELIMLIST));
- strcpy(d->group, "system");
- strcpy(d->delim, "c");
- d->back = NULL;
-
- m = (DMAP *) malloc(sizeof (DMAP));
- m->order = 1;
- m->type = ONE;
- bzero(m->bits, sizeof(m->bits));
- for (i = ' '; i <= '~'; i++)
- set(m->bits, i);
- m->next = NULL;
- d->maptr = m;
- Delimhead = d;
-
-
- d = (DELIMLIST * ) malloc(sizeof(DELIMLIST));
- strcpy(d->group, "system");
- strcpy(d->delim, "w");
- d->back = NULL;
- m = (DMAP *) malloc(sizeof (DMAP));
- m->order = 1;
- m->type = ONE;
- bzero(m->bits, sizeof(m->bits));
- for (i = 'A'; i <= 'Z'; i++)
- set(m->bits, i);
- for (i = 'a'; i <= 'z'; i++)
- set(m->bits, i);
- d->maptr = m;
-
- m2 = (DMAP *) malloc(sizeof(DMAP));
- m2->order = 2;
- m2->type = ZEROMORE;
- bzero(m2->bits, sizeof(m->bits));
- for (i = 'A'; i <= 'Z'; i++)
- set(m2->bits, i);
- for (i = 'a'; i <= 'z'; i++)
- set(m2->bits, i);
- m->next = m2;
- m2->next = NULL;
-
- d->back = Delimhead;
- Delimhead = d;
- }
-
-
-
-
-
- /*
- ** PRLIST -- print contents of delimiter queue
- */
- prlist(d)
- struct delimlist *d;
- {
- struct delimlist *q;
- DMAP *m;
- int i;
-
- printf("DELIM QUEUE:\n");
- q = d;
- while (q != NULL)
- {
- printf("-------------------------------------------------------\n");
- printf("NODE: group= %s, delim = %s \n", q->group, q->delim);
- m = q->maptr;
- while (m != NULL)
- {
- printf("maps:\n");
- printf("order = %d, type = %d \n", m->order, m->type);
- for (i = 0; i < ACHARS; i++)
- printf("%d ", test(m->bits,i));
- printf("\n");
- m = m->next;
- }
- q = q->back;
- printf("-------------------------------------------------------\n");
- }
-
- return(0);
-
- }
-
- /*
- ** SHRINK_LIST -- remove the delims in specified group from list
- **
- ** Parameters:
- ** group - name of the group to remove
- **
- */
- shrink_list(group)
- char *group;
- {
- struct delimlist *p, *q;
-
- /* may not delete sytem delims */
- if (!strcmp(group, "system"))
- return(-1);
-
- p = Delimhead;
-
- while ((p != NULL) && (strcmp(p->group, group)))
- {
- q = p;
- p = p->back;
- }
- if (p == NULL)
- {
- return(-1); /* error group not found */
- }
-
- while(!strcmp(p->group, group))
- {
- if (p == Delimhead)
- Delimhead = p->back;
- else
- q->back = p->back;
-
- if (p->back == NULL)
- {
- return(0);
- }
-
- p = p-> back;
- }
-
- /* prlist(Delimhead); */
- return(0);
- }
-
- /*
- ** DESTROY_DELIM -- remove the group of delims from the relation 'rdelim'
- **
- ** Parameters:
- ** group - the group of delims to remove
- **
- ** Called By:
- ** grammar.y
- **
- ** Returns:
- ** 0 if delims were successfully removed
- ** -1 if delims were not found in relation
- */
- destroy_delim(desc, group)
- DESC *desc;
- char *group;
- {
- DELIM_TUP tuple;
- TID lotid,hitid;
- int notfound = 1;
-
- if (find(desc,LRANGEKEY, &lotid, &hitid, group) < 0)
- return(-1);
- find(desc,HRANGEKEY, &lotid, &hitid, group);
-
- while (!get(desc, &lotid, &hitid, &tuple, 1))
- {
- if (!strcmp(tuple.group, group))
- {
- notfound = 0;
- delete(desc,&lotid);
- }
- }
- if (notfound)
- return(-1);
- return(0);
- }
-